﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using PRET.ReportDataDefine.UIData;

namespace PRET.ReportControlLib.Controls
{
    public partial class CheckTimePanel : UserControl
    {
        private readonly static string[] Months = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" };
        private readonly static string[] ProductionLins = {"A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "A16"};
        private readonly static string[] OrderTypes = { "MO", "MF", "MR", "MS", "MY", "QM" };
        private string currentOrderID = "";
        private List<OrderCheckInfo> orderList = new List<OrderCheckInfo>();
        private List<OrderCheckInfo> selectYearOrderList = new List<OrderCheckInfo>();
        public event CorrectOrderTimeEventHandle correctTimeEvent;
        public event IgnoreOrderTimeEventHandle ignoreTimeEvent;
        public event ShowReportViewEventHandle showReportEvent;
        public readonly static string CORRECT_SYS_TIME = "忽略ERP时间";
        public readonly static string IGNORE_ERP_TIME = "忽略PLC时间";
        private bool initFinish = false;
       
        public OrderCheckInfo GetOrderCheckInfo()
        {
            if (this.orderIDCombox.Items.Count == 0)
                return null;

            string orderID = (string)this.orderIDCombox.SelectedItem;
            string proLine = (string)this.proLineComboBox.SelectedItem;
            foreach (OrderCheckInfo obj in orderList)
            {
                if (obj.OrderID == orderID && obj.ProductionLine == proLine)
                {
                    obj.SelectSign = this.timeSelectCombox.SelectedIndex + 1;
                    return obj;
                }
            }
            return null;
        }

        public DateTime GetSelectedYearMonth
        {
            get
            {
                string year = this.dateTimePicker.Value.ToString("yyyy-MM");
                return DateTime.Parse(year);
            }
        }

        public void EnableControls(bool sign)
        {
            this.dateTimePicker.Enabled = sign;
            this.proLineComboBox.Enabled = sign;
            this.orderTypeComboBox.Enabled = sign;
            this.orderIDCombox.Enabled = sign;
            this.timeSelectCombox.Enabled = sign;
            this.correctBtn.Enabled = sign;
            this.reportViewBtn.Enabled = sign;
        }

        public CheckTimePanel()
        {
            InitializeComponent();
            InitializeYearsMonths();
        }

        private void InitializeYearsMonths()
        {
            // 初始化月
            this.dateTimePicker.Value = DateTime.Today;
            this.dateTimePicker.MaxDate = DateTime.Today;
            //this.monthCombox.DataSource = Months;
            //// 初始化年
            //int count = DateTime.Now.Year - StartYear;
            //List<string> ds = new List<string>();
            //for (int i = 0; i <= count; i++)
            //{
            //    int year = StartYear + i;
            //    ds.Add(year.ToString());
            //}
            //this.yearCombox.DataSource = ds;
            // 初始化生产线
            this.proLineComboBox.DataSource = ProductionLins;
            this.orderTypeComboBox.DataSource = OrderTypes;
            this.initFinish = true;
        }

        public void InitializeOrderIDPanel(List<OrderCheckInfo> orderList)
        {
            this.orderList = orderList;
            ShowOrderByYear();
            ShowNoMatchOrder();
        }
        /// <summary>
        /// 在promptTextBox里面显示系统记录时间和ERP记录时间不匹配的订单号
        /// </summary>
        private void ShowNoMatchOrder()
        {
            //this.promptTextBox.Text = "";
            //string tmptxt = "";
            //int count = 0;
            //foreach (OrderCheckInfo item in this.selectYearOrderList)
            //{
            //    if (RecordTimeIsMatch(item) == false)
            //    {
            //        tmptxt += string.Format("订单{0}的记录时间出现明显不一致.\r\n", item.OrderID);
            //        count++;
            //    }
            //}
            //this.promptTextBox.Text = string.Format("{2}月份一共有{0}个订单出现记录时间不一致：\r\n{1}", count, tmptxt, this.dateTimePicker.Value.Month);
        }

        private void correctBtn_Click(object sender, EventArgs e)
        {
            if (this.timeSelectCombox.SelectedIndex == 0)
            {
                // 按照ERP给定的时间纠正系统记录时间
                if (correctTimeEvent != null)
                {
                    CorrectOrderTimeEventArgs eventArg = new CorrectOrderTimeEventArgs(this.GetOrderCheckInfo());
                    correctTimeEvent(this, eventArg);
                }
                // 纠正系统时间到DB中， 同时要从text area区域里面删除相应的记录
                CorrectOrderTime();
            }
            else if (this.timeSelectCombox.SelectedIndex == 1)
            {
                // 忽略ERP给的纠正时间
                IgnoreERPOrderTime();
                // 忽略ERP提供的订单开始、结束时间
                if (ignoreTimeEvent != null)
                {
                    CorrectOrderTimeEventArgs eventArg = new CorrectOrderTimeEventArgs(this.GetOrderCheckInfo());
                    ignoreTimeEvent(this, eventArg);
                }
            }
        }

        private void orderIDCombox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (currentOrderID == (string)this.orderIDCombox.SelectedItem)
            //    return;

            currentOrderID = (string)this.orderIDCombox.SelectedItem; 
            string proLine = (string)this.proLineComboBox.SelectedItem;
            foreach(OrderCheckInfo item in this.orderList)
            {
                if(currentOrderID == item.OrderID && item.ProductionLine == proLine)
                {
                    if (item.SelectSign == 1)
                    {
                        this.timeSelectCombox.SelectedIndex = 0;
                        this.correctBtn.Text = CORRECT_SYS_TIME;
                    }
                    else
                    {
                        this.timeSelectCombox.SelectedIndex = 1;
                        this.correctBtn.Text = IGNORE_ERP_TIME;
                    }
                    this.showTimeList(item.SystemRecord, item.ERPRecord);
                    ShowPromptMessage(item);
                    break;
                }
            }
        }
        private void ShowPromptMessage(OrderCheckInfo order)
        {
            this.correctBtn.Enabled = false;
            DisplayDifferentTime(false);
            //this.signLable.Visible = false;
            if (order.SystemRecord == null || order.SystemRecord.Count == 0)
            {
                DisplayDifferentTime(true);
                //this.signLable.Visible = true;
                if (this.timeSelectCombox.SelectedIndex == 0)
                    this.correctBtn.Enabled = true;
                return;
            }
            if (order.ERPRecord == null || order.ERPRecord.Count == 0)
            {
                DisplayDifferentTime(false);
                //this.signLable.Visible = false;
                if (this.timeSelectCombox.SelectedIndex == 0)
                    this.correctBtn.Enabled = false;
                return ;
            }

            if (order.IsIgnore == 1)
                return;

            // 如果系统记录时间和ERP修正时间在数量上不一样， 则提示用户两个时间有明显差异
            if (order.SystemRecord.Count != order.ERPRecord.Count)
            {
                DisplayDifferentTime(true);
                //this.signLable.Visible = true;
                this.correctBtn.Enabled = true;
                return;
            }
            else
            {
                int count = order.SystemRecord.Count;
                for(int i = 0; i < count; i++)
                {
                    if (order.SystemRecord[i].EndTime == null || order.ERPRecord[i].EndTime == null)
                    {
                        DisplayDifferentTime(true);
                        //this.signLable.Visible = true;
                        this.correctBtn.Enabled = true;
                        return;
                    }
                    TimeSpan startSpan = (TimeSpan)(order.SystemRecord[i].StartTime - order.ERPRecord[i].StartTime);
                    TimeSpan endSpan = (TimeSpan)(order.SystemRecord[i].EndTime - order.ERPRecord[i].EndTime);
                    double interStart = startSpan.TotalHours;
                    double interEnd = endSpan.TotalHours;
                    if (interStart > 1 || interEnd > 1)
                    {
                        DisplayDifferentTime(true);
                        //this.signLable.Visible = true;
                        this.correctBtn.Enabled = true;
                        return;
                    }
                }
            }
        }
        private bool RecordTimeIsMatch(OrderCheckInfo order)
        {
            // 如果用户之前忽略过这个时间差异
            if (order.IsIgnore == 1)
                return true;

            if (order.ERPRecord == null || order.ERPRecord.Count == 0)
            {
                return true;
            }
            if (order.SystemRecord == null || order.SystemRecord.Count == 0)
            {
                return false;
            }

            // 如果系统记录时间和ERP修正时间在数量上不一样， 则提示用户两个时间有明显差异
            if (order.SystemRecord.Count != order.ERPRecord.Count)
            {
                return false;
            }
            else
            {
                int count = order.SystemRecord.Count;
                for (int i = 0; i < count; i++)
                {
                    if (order.SystemRecord[i].EndTime == null || order.ERPRecord[i].EndTime == null)
                        return false;
                    TimeSpan startSpan = (TimeSpan)(order.SystemRecord[i].StartTime - order.ERPRecord[i].StartTime);
                    TimeSpan endSpan = (TimeSpan)(order.SystemRecord[i].EndTime - order.ERPRecord[i].EndTime);
                    double interStart = startSpan.TotalHours;
                    double interEnd = endSpan.TotalHours;
                    // 如果时间相差间隔在1小时以上
                    if (interStart > 1 || interEnd > 1)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        private void CorrectOrderTime()
        {
            OrderCheckInfo currentOrder = this.GetOrderCheckInfo();
            if (currentOrder == null)
                return;
            if (currentOrder.ERPRecord == null || currentOrder.ERPRecord.Count == 0)
                return;
            currentOrder.SystemRecord = currentOrder.ERPRecord;
            showTimeList(currentOrder.SystemRecord, currentOrder.ERPRecord);
            // 更新List<OrderCheckInfo>
            for(int i = 0; i < this.orderList.Count; i++)
            {
                if (currentOrder.OrderID == this.orderList[i].OrderID)
                {
                    this.orderList[i] = currentOrder;
                    break;
                }
            }

            DisplayDifferentTime(false);
            //this.signLable.Visible = false;
            this.correctBtn.Enabled = false;
            ShowNoMatchOrder();
        }

        private void IgnoreERPOrderTime()
        {
            OrderCheckInfo currentOrder = this.GetOrderCheckInfo();
            currentOrder.IsIgnore = 1;
            // 更新List<OrderCheckInfo>
            for (int i = 0; i < this.orderList.Count; i++)
            {
                if (currentOrder.OrderID == this.orderList[i].OrderID)
                {
                    this.orderList[i] = currentOrder;
                    break;
                }
            }
            ShowPromptMessage(currentOrder);
            ShowNoMatchOrder();
        }

        private void timeSelectCombox_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.reportViewBtn.Enabled = true;
            OrderCheckInfo item = GetOrderCheckInfo();
            if (item == null)
                return;
            if (this.timeSelectCombox.SelectedIndex == 0)
            {
                this.correctBtn.Text = CORRECT_SYS_TIME;
                if (item.SystemRecord == null || item.SystemRecord.Count == 0)
                    this.reportViewBtn.Enabled = false;
            }
            else if(this.timeSelectCombox.SelectedIndex == 1)
            {
                this.correctBtn.Text = IGNORE_ERP_TIME;
                if (item.ERPRecord == null || item.ERPRecord.Count == 0)
                    this.reportViewBtn.Enabled = false;                
            }
            this.showTimeList(item.SystemRecord, item.ERPRecord);
            ShowPromptMessage(item);
        }

        private void showTimeList(List<OrderCheckDetail> sysTimeList, List<OrderCheckDetail> erpTimeList)
        {
            this.timeDataGridView.Rows.Clear();
            int sysCount = 0, erpCount = 0;
            if (sysTimeList != null && sysTimeList.Count > 0)
                sysCount = sysTimeList.Count;
            if (erpTimeList != null && erpTimeList.Count > 0)
                erpCount = erpTimeList.Count;
            for (int i = 0; i < sysCount || i < erpCount; i++)
            {
                string sysStart = "", sysEnd = "", erpStart = "", erpEnd = "";
                if (i < sysCount)
                {
                    sysStart = sysTimeList[i].StartTime.ToString();
                    if (sysTimeList[i].EndTime != null)
                        sysEnd = sysTimeList[i].EndTime.ToString();
                }
                if (i < erpCount)
                {
                    erpStart = erpTimeList[i].StartTime.ToString();
                    if (erpTimeList[i].EndTime != null)
                        erpEnd = erpTimeList[i].EndTime.ToString();
                }
                int index = this.timeDataGridView.Rows.Add();
                this.timeDataGridView.Rows[index].Cells[0].Value = sysStart;
                this.timeDataGridView.Rows[index].Cells[1].Value = sysEnd;
                this.timeDataGridView.Rows[index].Cells[2].Value = erpStart;
                this.timeDataGridView.Rows[index].Cells[3].Value = erpEnd;
            }
        }

        private void timeRangeCombox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (initFinish)
            {
                ShowOrderByYear();
                ShowNoMatchOrder();
            }
        }

        private void ShowOrderByYear()
        {
            if (this.orderList == null)
                return;

            this.selectYearOrderList.Clear();
            DateTime startTime = this.GetSelectedYearMonth;
            DateTime endTime = startTime.AddMonths(1);
            List<string> ds = new List<string>();
            foreach (OrderCheckInfo item in this.orderList)
            {
                string ordType = item.OrderID.Substring(0, 2);
                if (item.OrderID.Length > 12)
                    ordType = item.OrderID.Substring(2, 2);
                // 先找系统时间内的
                if (item.SystemRecord != null && item.SystemRecord.Count > 0 &&
                    item.SystemRecord[0].StartTime >= startTime && item.SystemRecord[0].StartTime <= endTime)
                {
                    if (item.ProductionLine == this.proLineComboBox.SelectedItem.ToString() &&
                        ordType == this.orderTypeComboBox.SelectedItem.ToString())
                    {
                        ds.Add(item.OrderID);
                        selectYearOrderList.Add(item);
                    }
                }
                // 再找ERP时间内的
                else if (item.ERPRecord != null && item.ERPRecord.Count > 0 &&
                    item.ERPRecord[0].StartTime >= startTime && item.ERPRecord[0].StartTime <= endTime)
                {
                    if (item.ProductionLine == this.proLineComboBox.SelectedItem.ToString() &&
                        ordType == this.orderTypeComboBox.SelectedItem.ToString())
                    {
                        ds.Add(item.OrderID);
                        selectYearOrderList.Add(item);
                    }                    
                }
            }
            this.orderIDCombox.DataSource = ds;
            this.timeSelectCombox.Enabled = true;
            this.reportViewBtn.Enabled = true;

            if (this.orderIDCombox.Items.Count == 0)
            {
                this.timeDataGridView.Rows.Clear();
                this.timeSelectCombox.Enabled = false;
                this.reportViewBtn.Enabled = false;
            }
        }

        private void reportViewBtn_Click(object sender, EventArgs e)
        {
            // 按照ERP给定的时间纠正系统记录时间
            if (showReportEvent != null)
            {
                ShowReportViewEventArgs eventArg = new ShowReportViewEventArgs(this.GetOrderCheckInfo());
                showReportEvent(this, eventArg);
            }
        }

        private void DisplayDifferentTime(bool hasDiff)
        {
            DataGridViewCellStyle style = this.timeDataGridView.DefaultCellStyle;
            if (hasDiff)
            {
                style.ForeColor = Color.DarkRed;
                style.SelectionForeColor = Color.Red;
            }
            else
            { 
                style.ForeColor = Color.Black;
                style.SelectionForeColor = Color.White;   
            }
            this.timeDataGridView.DefaultCellStyle = style;
        }
    }

    public delegate void CorrectOrderTimeEventHandle(object sender, CorrectOrderTimeEventArgs args);
    public delegate void IgnoreOrderTimeEventHandle(object sender, CorrectOrderTimeEventArgs args);
    public delegate void ShowReportViewEventHandle(object sender, ShowReportViewEventArgs args);
    // Define a class to hold custom event info
    public class CorrectOrderTimeEventArgs : EventArgs
    {
        public CorrectOrderTimeEventArgs(OrderCheckInfo obj)
        {
            order = obj;
        }
        private OrderCheckInfo order;

        public OrderCheckInfo Order
        {
            get { return order; }
            set { order = value; }
        }
    }

    public class ShowReportViewEventArgs: EventArgs
    {
        public ShowReportViewEventArgs(OrderCheckInfo obj)
        {
            order = obj;
        }
        private OrderCheckInfo order;

        public OrderCheckInfo Order
        {
            get { return order; }
            set { order = value; }
        }
    }
}
